;; Test `if` operator

(module
  (import "wasi" "print_i32_ln" (func $wasi$print_i32_ln (param i32)))
  (import "wasi" "print_i64_ln" (func $wasi$print_i64_ln (param i64)))
  ;; Auxiliary definition
  (memory 1)

  (func $dummy)

  (func $empty (export "empty") (param i32)
    (if (local.get 0) (then))
    (if (local.get 0) (then) (else))
    (if $l (local.get 0) (then))
    (if $l (local.get 0) (then) (else))
  )

  (func $singular (export "singular") (param i32) (result i32)
    (if (local.get 0) (then (nop)))
    (if (local.get 0) (then (nop)) (else (nop)))
    (if (result i32) (local.get 0) (then (i32.const 7)) (else (i32.const 8)))
  )

  (func $multi (export "multi") (param i32) (result i32 i32)
    (if (local.get 0) (then (call $dummy) (call $dummy) (call $dummy)))
    (if (local.get 0) (then) (else (call $dummy) (call $dummy) (call $dummy)))
    (if (result i32) (local.get 0)
      (then (call $dummy) (call $dummy) (i32.const 8) (call $dummy))
      (else (call $dummy) (call $dummy) (i32.const 9) (call $dummy))
    )
    (if (result i32 i64 i32) (local.get 0)
      (then
        (call $dummy) (call $dummy) (i32.const 1) (call $dummy)
        (call $dummy) (call $dummy) (i64.const 2) (call $dummy)
        (call $dummy) (call $dummy) (i32.const 3) (call $dummy)
      )
      (else
        (call $dummy) (call $dummy) (i32.const -1) (call $dummy)
        (call $dummy) (call $dummy) (i64.const -2) (call $dummy)
        (call $dummy) (call $dummy) (i32.const -3) (call $dummy)
      )
    )
    (drop) (drop)
  )

  (func $nested (export "nested") (param i32 i32) (result i32)
    (if (result i32) (local.get 0)
      (then
        (if (local.get 1) (then (call $dummy) (block) (nop)))
        (if (local.get 1) (then) (else (call $dummy) (block) (nop)))
        (if (result i32) (local.get 1)
          (then (call $dummy) (i32.const 9))
          (else (call $dummy) (i32.const 10))
        )
      )
      (else
        (if (local.get 1) (then (call $dummy) (block) (nop)))
        (if (local.get 1) (then) (else (call $dummy) (block) (nop)))
        (if (result i32) (local.get 1)
          (then (call $dummy) (i32.const 10))
          (else (call $dummy) (i32.const 11))
        )
      )
    )
  )

  (func $as_select_first (export "as_select_first") (param i32) (result i32)
    (select
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (i32.const 2) (i32.const 3)
    )
  )
  (func $as_select_mid (export "as_select_mid") (param i32) (result i32)
    (select
      (i32.const 2)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (i32.const 3)
    )
  )
  (func $as_select_last (export "as_select_last") (param i32) (result i32)
    (select
      (i32.const 2) (i32.const 3)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
    )
  )

  (func $as_loop_first (export "as_loop_first") (param i32) (result i32)
    (loop (result i32)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (call $dummy) (call $dummy)
    )
  )
  (func $as_loop_mid (export "as_loop_mid") (param i32) (result i32)
    (loop (result i32)
      (call $dummy)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (call $dummy)
    )
  )
  (func $as_loop_last (export "as_loop_last") (param i32) (result i32)
    (loop (result i32)
      (call $dummy) (call $dummy)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
    )
  )

  (func $as_if_condition (export "as_if_condition") (param i32) (result i32)
    (if (result i32)
      (if (result i32) (local.get 0)
        (then (i32.const 1)) (else (i32.const 0))
      )
      (then (call $dummy) (i32.const 2))
      (else (call $dummy) (i32.const 3))
    )
  )

  (func $as_br_if_first (export "as_br_if_first") (param i32) (result i32)
    (block (result i32)
      (br_if 0
        (if (result i32) (local.get 0)
          (then (call $dummy) (i32.const 1))
          (else (call $dummy) (i32.const 0))
        )
        (i32.const 2)
      )
      (return (i32.const 3))
    )
  )
  (func $as_br_if_last (export "as_br_if_last") (param i32) (result i32)
    (block (result i32)
      (br_if 0
        (i32.const 2)
        (if (result i32) (local.get 0)
          (then (call $dummy) (i32.const 1))
          (else (call $dummy) (i32.const 0))
        )
      )
      (return (i32.const 3))
    )
  )

  (func $as_br_table_first (export "as_br_table_first") (param i32) (result i32)
    (block (result i32)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (i32.const 2)
      (br_table 0 0)
    )
  )
  (func $as_br_table_last (export "as_br_table_last") (param i32) (result i32)
    (block (result i32)
      (i32.const 2)
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 1))
        (else (call $dummy) (i32.const 0))
      )
      (br_table 0 0)
    )
  )

  (func $func (param i32 i32) (result i32) (local.get 0))
  (type $check (func (param i32 i32) (result i32)))
  (table funcref (elem $func))
  (func $as_call_indirect_first (export "as_call_indirect_first") (param i32) (result i32)
    (block (result i32)
      (call_indirect (type $check)
        (if (result i32) (local.get 0)
          (then (call $dummy) (i32.const 1))
          (else (call $dummy) (i32.const 0))
        )
        (i32.const 2) (i32.const 0)
      )
    )
  )
  (func $as_call_indirect_mid (export "as_call_indirect_mid") (param i32) (result i32)
    (block (result i32)
      (call_indirect (type $check)
        (i32.const 2)
        (if (result i32) (local.get 0)
          (then (call $dummy) (i32.const 1))
          (else (call $dummy) (i32.const 0))
        )
        (i32.const 0)
      )
    )
  )
  (func $as_call_indirect_last (export "as_call_indirect_last") (param i32) (result i32)
    (block (result i32)
      (call_indirect (type $check)
        (i32.const 2) (i32.const 0)
        (if (result i32) (local.get 0)
          (then (call $dummy) (i32.const 1))
          (else (call $dummy) (i32.const 0))
        )
      )
    )
  )

  (func $as_store_first (export "as_store_first") (param i32)
    (if (result i32) (local.get 0)
      (then (call $dummy) (i32.const 1))
      (else (call $dummy) (i32.const 0))
    )
    (i32.const 2)
    (i32.store)
  )
  (func $as_store_last (export "as_store_last") (param i32)
    (i32.const 2)
    (if (result i32) (local.get 0)
      (then (call $dummy) (i32.const 1))
      (else (call $dummy) (i32.const 0))
    )
    (i32.store)
  )

  (func $as_memory_grow_value (export "as_memory_grow_value") (param i32) (result i32)
    (memory.grow
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    )
  )

  (func $f (param i32) (result i32) (local.get 0))

  (func $as_call_value (export "as_call_value") (param i32) (result i32)
    (call $f
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    )
  )
  (func $as_return_value (export "as_return_value") (param i32) (result i32)
    (if (result i32) (local.get 0)
      (then (i32.const 1))
      (else (i32.const 0)))
    (return)
  )
  (func $as_drop_operand (export "as_drop_operand") (param i32)
    (drop
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    )
  )
  (func $as_br_value (export "as_br_value") (param i32) (result i32)
    (block (result i32)
      (br 0
        (if (result i32) (local.get 0)
          (then (i32.const 1))
          (else (i32.const 0))
        )
      )
    )
  )
  (func $as_local_set_value (export "as_local_set_value") (param i32) (result i32)
    (local i32)
    (local.set 0
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    )
    (local.get 0)
  )
  (func $as_local_tee_value (export "as_local_tee_value") (param i32) (result i32)
    (local.tee 0
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    )
  )
  (global $a (mut i32) (i32.const 10))
  (func $as_global_set_value (export "as_global_set_value") (param i32) (result i32)
    (global.set $a
      (if (result i32) (local.get 0)
        (then (i32.const 1))
        (else (i32.const 0))
      )
    ) (global.get $a)
  )
  (func $as_load_operand (export "as_load_operand") (param i32) (result i32)
    (i32.load
      (if (result i32) (local.get 0)
        (then (i32.const 11))
        (else (i32.const 10))
      )
    )
  )

  (func $as_unary_operand (export "as_unary_operand") (param i32) (result i32)
    (i32.ctz
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 13))
        (else (call $dummy) (i32.const -13))
      )
    )
  )
  (func $as_binary_operand (export "as_binary_operand") (param i32 i32) (result i32)
    (i32.mul
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 3))
        (else (call $dummy) (i32.const -3))
      )
      (if (result i32) (local.get 1)
        (then (call $dummy) (i32.const 4))
        (else (call $dummy) (i32.const -5))
      )
    )
  )
  (func $as_test_operand (export "as_test_operand") (param i32) (result i32)
    (i32.eqz
      (if (result i32) (local.get 0)
        (then (call $dummy) (i32.const 13))
        (else (call $dummy) (i32.const 0))
      )
    )
  )
  (func $as_compare_operand (export "as_compare_operand") (param i32 i32) (result i32)
    (f32.gt
      (if (result f32) (local.get 0)
        (then (call $dummy) (f32.const 3))
        (else (call $dummy) (f32.const -3))
      )
      (if (result f32) (local.get 1)
        (then (call $dummy) (f32.const 4))
        (else (call $dummy) (f32.const -4))
      )
    )
  )
  (func $as_binary_operands (export "as_binary_operands") (param i32) (result i32)
    (i32.mul
      (if (result i32 i32) (local.get 0)
        (then (call $dummy) (i32.const 3) (call $dummy) (i32.const 4))
        (else (call $dummy) (i32.const 3) (call $dummy) (i32.const -4))
      )
    )
  )
  (func $as_compare_operands (export "as_compare_operands") (param i32) (result i32)
    (f32.gt
      (if (result f32 f32) (local.get 0)
        (then (call $dummy) (f32.const 3) (call $dummy) (f32.const 3))
        (else (call $dummy) (f32.const -2) (call $dummy) (f32.const -3))
      )
    )
  )
  (func $as_mixed_operands (export "as_mixed_operands") (param i32) (result i32)
    (if (result i32 i32) (local.get 0)
      (then (call $dummy) (i32.const 3) (call $dummy) (i32.const 4))
      (else (call $dummy) (i32.const -3) (call $dummy) (i32.const -4))
    )
    (i32.const 5)
    (i32.add)
    (i32.mul)
  )

  (func $break_bare (export "break_bare") (result i32)
    (if (i32.const 1) (then (br 0) (unreachable)))
    (if (i32.const 1) (then (br 0) (unreachable)) (else (unreachable)))
    (if (i32.const 0) (then (unreachable)) (else (br 0) (unreachable)))
    (if (i32.const 1) (then (br_if 0 (i32.const 1)) (unreachable)))
    (if (i32.const 1) (then (br_if 0 (i32.const 1)) (unreachable)) (else (unreachable)))
    (if (i32.const 0) (then (unreachable)) (else (br_if 0 (i32.const 1)) (unreachable)))
    (if (i32.const 1) (then (br_table 0 (i32.const 0)) (unreachable)))
    (if (i32.const 1) (then (br_table 0 (i32.const 0)) (unreachable)) (else (unreachable)))
    (if (i32.const 0) (then (unreachable)) (else (br_table 0 (i32.const 0)) (unreachable)))
    (i32.const 19)
  )

  (func $break_value (export "break_value") (param i32) (result i32)
    (if (result i32) (local.get 0)
      (then (br 0 (i32.const 18)))
      (else (br 0 (i32.const 21)))
    )
  )
  (func $break_multi_value (export "break_multi_value") (param i32) (result i32 i32 i64)
    (if (result i32 i32 i64) (local.get 0)
      (then
        (br 0 (i32.const 18) (i32.const -18) (i64.const 18))
      )
      (else
        (br 0 (i32.const -18) (i32.const 18) (i64.const -18))
      )
    )
  )

  (func $param (export "param") (param i32) (result i32)
    (i32.const 1)
    (if (param i32) (result i32)
      (local.get 0)
      (then (i32.const 2)
            (i32.add))
      (else (i32.const -2)
             (i32.add))
    )
    )

  (func $params (export "params") (param i32) (result i32)
    (i32.const 1)
    (i32.const 2)
    (if (param i32 i32) (result i32)
      (local.get 0)
        (then (i32.add))
        (else (i32.sub))
    )
  )
  (func $params_id (export "params_id") (param i32) (result i32)
    (i32.const 1)
    (i32.const 2)
    (if (param i32 i32) (result i32 i32) (local.get 0) (then))
    (i32.add)
  )
  (func $param_break (export "param_break") (param i32) (result i32)
    (i32.const 1)
    (if (param i32) (result i32) (local.get 0)
      (then (i32.const 2) (i32.add) (br 0))
      (else (i32.const -2) (i32.add) (br 0))
    )
  )
  (func $params_break (export "params_break") (param i32) (result i32)
    (i32.const 1)
    (i32.const 2)
    (if (param i32 i32) (result i32) (local.get 0)
      (then (i32.add) (br 0))
      (else (i32.sub) (br 0))
    )
  )
  (func $params_id_break (export "params_id_break") (param i32) (result i32)
    (i32.const 1)
    (i32.const 2)
    (if (param i32 i32) (result i32 i32) (local.get 0) (then (br 0)))
    (i32.add)
  )

  (func $effects (export "effects") (param i32) (result i32)
    (local i32)
    (if
      (block (result i32) (local.set 1 (i32.const 1)) (local.get 0))
      (then
        (local.set 1 (i32.mul (local.get 1) (i32.const 3)))
        (local.set 1 (i32.sub (local.get 1) (i32.const 5)))
        (local.set 1 (i32.mul (local.get 1) (i32.const 7)))
        (br 0)
        (local.set 1 (i32.mul (local.get 1) (i32.const 100)))
      )
      (else
        (local.set 1 (i32.mul (local.get 1) (i32.const 5)))
        (local.set 1 (i32.sub (local.get 1) (i32.const 7)))
        (local.set 1 (i32.mul (local.get 1) (i32.const 3)))
        (br 0)
        (local.set 1 (i32.mul (local.get 1) (i32.const 1000)))
      )
    )
    (local.get 1)
  )

  ;; Examples

  (func $add64_u_with_carry (export "add64_u_with_carry")
    (param $i i64) (param $j i64) (param $c i32) (result i64 i32)
    (local $k i64)
    (local.set $k
      (i64.add
        (i64.add (local.get $i) (local.get $j))
        (i64.extend_i32_u (local.get $c))
      )
    )
    (return (local.get $k) (i64.lt_u (local.get $k) (local.get $i)))
  )

  (func $add64_u_saturated (export "add64_u_saturated")
    (param i64 i64) (result i64)
    (call $add64_u_with_carry (local.get 0) (local.get 1) (i32.const 0))
    (if (param i64) (result i64)
      (then (drop) (i64.const -1))
    )
  )

  ;; Block signature syntax

  (type $block-sig-1 (func))
  (type $block-sig-2 (func (result i32)))
  (type $block-sig-3 (func (param $x i32)))
  (type $block-sig-4 (func (param i32 f64 i32) (result i32 f64 i32)))

  (func $type_use (export "type_use")
    (if (type $block-sig-1) (i32.const 1) (then))
    (if (type $block-sig-2) (i32.const 1)
      (then (i32.const 0)) (else (i32.const 2))
    )
    (if (type $block-sig-3) (i32.const 1) (then (drop)) (else (drop)))
    (i32.const 0) (f64.const 0) (i32.const 0)
    (if (type $block-sig-4) (i32.const 1) (then))
    (drop) (drop) (drop)
    (if (type $block-sig-2) (result i32) (i32.const 1)
      (then (i32.const 0)) (else (i32.const 2))
    )
    (if (type $block-sig-3) (param i32) (i32.const 1)
      (then (drop)) (else (drop))
    )
    (i32.const 0) (f64.const 0) (i32.const 0)
    (if (type $block-sig-4)
      (param i32) (param f64 i32) (result i32 f64) (result i32)
      (i32.const 1) (then)
    )
    (drop) (drop) (drop)
  )

(func $assert_eq_i32 (param $line i32) (param $x i32) (param $y i32)
       (if (i32.ne (local.get 1) (local.get 2))
           (then
	       (call $wasi$print_i32_ln  (local.get 0))
	       (call $wasi$print_i32_ln  (local.get 1))
	       (call $wasi$print_i32_ln  (local.get 2))
	       (unreachable))
       )
 )

 (func $assert_eq_i64 (param $line i32) (param $x i64) (param $y i64)
       (if (i64.ne (local.get 1) (local.get 2))
           (then
	       (call $wasi$print_i32_ln  (local.get 0))
	       (call $wasi$print_i64_ln  (local.get 1))
	       (call $wasi$print_i64_ln  (local.get 2))
	       (unreachable))
       )
 )

(func $assert_eq_i32_i32_i64 (param $line i32) (param $a i32) (param $b i32)  (param $c i64)
        (param $x i32)  (param $y i32)  (param $z i64)
       (call $assert_eq_i32  (local.get 0)   (local.get $a)  (local.get $x))
       (call $assert_eq_i32  (local.get 0)   (local.get $b)  (local.get $y))
       (call $assert_eq_i64  (local.get 0)   (local.get $c)  (local.get $z))
)

(func $assert_eq_i32_i32 (param $line i32) (param $a i32) (param $b i32)
        (param $x i32)  (param $y i32)
       (call $assert_eq_i32  (local.get 0)   (local.get $a)  (local.get $x))
       (call $assert_eq_i32  (local.get 0)   (local.get $b)  (local.get $y))
)

(func $assert_eq_i64_i32 (param $line i32) (param $a i64)
        (param $b i32)  (param $x i64)  (param $y i32)
       (call $assert_eq_i64  (local.get 0)   (local.get $a)  (local.get $x))
       (call $assert_eq_i32  (local.get 0)   (local.get $b)  (local.get $y))
)

(func $main (export "_start")
(call $empty (i32.const 0))
(call $empty (i32.const 1))
(call $empty (i32.const 100))
(call $empty (i32.const -2))

(call $assert_eq_i32 (i32.const 1201) (call $singular (i32.const 0)) (i32.const 8))
(call $assert_eq_i32 (i32.const 1202) (call $singular (i32.const 1)) (i32.const 7))
(call $assert_eq_i32 (i32.const 1203) (call $singular (i32.const 10)) (i32.const 7))
(call $assert_eq_i32 (i32.const 1204) (call $singular (i32.const -10)) (i32.const 7))

(call $assert_eq_i32_i32 (i32.const 1301) (call $multi (i32.const 0)) (i32.const 9) (i32.const -1))
(call $assert_eq_i32_i32 (i32.const 1302) (call $multi (i32.const 1)) (i32.const 8) (i32.const 1))
(call $assert_eq_i32_i32 (i32.const 1303) (call $multi (i32.const 13)) (i32.const 8) (i32.const 1))
(call $assert_eq_i32_i32 (i32.const 1304) (call $multi (i32.const -5)) (i32.const 8) (i32.const 1))

(call $assert_eq_i32 (i32.const 1401) (call $nested (i32.const 0) (i32.const 0)) (i32.const 11))
(call $assert_eq_i32 (i32.const 1402) (call $nested (i32.const 1) (i32.const 0)) (i32.const 10))
(call $assert_eq_i32 (i32.const 1403) (call $nested (i32.const 0) (i32.const 1)) (i32.const 10))
(call $assert_eq_i32 (i32.const 1404) (call $nested (i32.const 3) (i32.const 2)) (i32.const 9))
(call $assert_eq_i32 (i32.const 1405) (call $nested (i32.const 0) (i32.const -100)) (i32.const 10))
(call $assert_eq_i32 (i32.const 1406) (call $nested (i32.const 10) (i32.const 10)) (i32.const 9))
(call $assert_eq_i32 (i32.const 1407) (call $nested (i32.const 0) (i32.const -1)) (i32.const 10))
(call $assert_eq_i32 (i32.const 1408) (call $nested (i32.const -111) (i32.const -2)) (i32.const 9))

(call $assert_eq_i32 (i32.const 1501) (call $as_select_first (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 1502) (call $as_select_first (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 1601) (call $as_select_mid (i32.const 0)) (i32.const 2))
(call $assert_eq_i32 (i32.const 1602) (call $as_select_mid (i32.const 1)) (i32.const 2))
(call $assert_eq_i32 (i32.const 1701) (call $as_select_last (i32.const 0)) (i32.const 3))
(call $assert_eq_i32 (i32.const 1702) (call $as_select_last (i32.const 1)) (i32.const 2))

(call $assert_eq_i32 (i32.const 1801) (call $as_loop_first (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 1802) (call $as_loop_first (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 1901) (call $as_loop_mid (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 1902) (call $as_loop_mid (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 2001) (call $as_loop_last (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 2002) (call $as_loop_last (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 2101) (call $as_if_condition (i32.const 0)) (i32.const 3))
(call $assert_eq_i32 (i32.const 2102) (call $as_if_condition (i32.const 1)) (i32.const 2))

(call $assert_eq_i32 (i32.const 2201) (call $as_br_if_first (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 2202) (call $as_br_if_first (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 2301) (call $as_br_if_last (i32.const 0)) (i32.const 3))
(call $assert_eq_i32 (i32.const 2302) (call $as_br_if_last (i32.const 1)) (i32.const 2))

(call $assert_eq_i32 (i32.const 2401) (call $as_br_table_first (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 2402) (call $as_br_table_first (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 2501) (call $as_br_table_last (i32.const 0)) (i32.const 2))
(call $assert_eq_i32 (i32.const 2502) (call $as_br_table_last (i32.const 1)) (i32.const 2))

(call $assert_eq_i32 (i32.const 2601) (call $as_call_indirect_first (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 2602) (call $as_call_indirect_first (i32.const 1)) (i32.const 1))
(call $assert_eq_i32 (i32.const 2701) (call $as_call_indirect_mid (i32.const 0)) (i32.const 2))
(call $assert_eq_i32 (i32.const 2702) (call $as_call_indirect_mid (i32.const 1)) (i32.const 2))
(call $assert_eq_i32 (i32.const 2801) (call $as_call_indirect_last (i32.const 0)) (i32.const 2))

(call $as_store_first (i32.const 0))
(call $as_store_first (i32.const 1))
(call $as_store_last (i32.const 0))
(call $as_store_last (i32.const 1))

(call $assert_eq_i32 (i32.const 3101) (call $as_memory_grow_value (i32.const 0)) (i32.const 1))
(call $assert_eq_i32 (i32.const 3102) (call $as_memory_grow_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3201) (call $as_call_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3202) (call $as_call_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3301) (call $as_return_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3302) (call $as_return_value (i32.const 1)) (i32.const 1))

(call $as_drop_operand (i32.const 0))
(call $as_drop_operand (i32.const 1))

(call $assert_eq_i32 (i32.const 3501) (call $as_br_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3502) (call $as_br_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3601) (call $as_local_set_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3602) (call $as_local_set_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3701) (call $as_local_tee_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3702) (call $as_local_tee_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3801) (call $as_global_set_value (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3802) (call $as_global_set_value (i32.const 1)) (i32.const 1))

(call $assert_eq_i32 (i32.const 3901) (call $as_load_operand (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 3902) (call $as_load_operand (i32.const 1)) (i32.const 0))

(call $assert_eq_i32 (i32.const 4001) (call $as_unary_operand (i32.const 0)) (i32.const 0))
(call $assert_eq_i32 (i32.const 4002) (call $as_unary_operand (i32.const 1)) (i32.const 0))
(call $assert_eq_i32 (i32.const 4003) (call $as_unary_operand (i32.const -1)) (i32.const 0))

(call $assert_eq_i32 (i32.const 4101) (call $as_binary_operand (i32.const 0) (i32.const 0)) (i32.const 15))
(call $assert_eq_i32 (i32.const 4102) (call $as_binary_operand (i32.const 0) (i32.const 1)) (i32.const -12))
(call $assert_eq_i32 (i32.const 4103) (call $as_binary_operand (i32.const 1) (i32.const 0)) (i32.const -15))
(call $assert_eq_i32 (i32.const 4104) (call $as_binary_operand (i32.const 1) (i32.const 1)) (i32.const 12))

(call $assert_eq_i32 (i32.const 4201) (call $as_test_operand (i32.const 0)) (i32.const 1))
(call $assert_eq_i32 (i32.const 4202) (call $as_test_operand (i32.const 1)) (i32.const 0))

(call $assert_eq_i32 (i32.const 4301) (call $as_compare_operand (i32.const 0) (i32.const 0)) (i32.const 1))
(call $assert_eq_i32 (i32.const 4302) (call $as_compare_operand (i32.const 0) (i32.const 1)) (i32.const 0))
(call $assert_eq_i32 (i32.const 4303) (call $as_compare_operand (i32.const 1) (i32.const 0)) (i32.const 1))
(call $assert_eq_i32 (i32.const 4304) (call $as_compare_operand (i32.const 1) (i32.const 1)) (i32.const 0))

(call $assert_eq_i32 (i32.const 4401) (call $as_binary_operands (i32.const 0)) (i32.const -12))
(call $assert_eq_i32 (i32.const 4402) (call $as_binary_operands (i32.const 1)) (i32.const 12))

(call $assert_eq_i32 (i32.const 4501) (call $as_compare_operands (i32.const 0)) (i32.const 1))
(call $assert_eq_i32 (i32.const 4502) (call $as_compare_operands (i32.const 1)) (i32.const 0))

(call $assert_eq_i32 (i32.const 4601) (call $as_mixed_operands (i32.const 0)) (i32.const -3))
(call $assert_eq_i32 (i32.const 4602) (call $as_mixed_operands (i32.const 1)) (i32.const 27))

(call $assert_eq_i32 (i32.const 4701) (call $break_bare ) (i32.const 19))
(call $assert_eq_i32 (i32.const 4801) (call $break_value (i32.const 1)) (i32.const 18))
(call $assert_eq_i32 (i32.const 4802) (call $break_value (i32.const 0)) (i32.const 21))
(call $assert_eq_i32_i32_i64 (i32.const 4901) (call $break_multi_value (i32.const 0)) (i32.const -18) (i32.const 18) (i64.const -18))
(call $assert_eq_i32_i32_i64 (i32.const 4902) (call $break_multi_value (i32.const 1)) (i32.const 18) (i32.const -18) (i64.const 18))

(call $assert_eq_i32 (i32.const 5001) (call $param (i32.const 0)) (i32.const -1))
(call $assert_eq_i32 (i32.const 5002) (call $param (i32.const 1)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5101) (call $params (i32.const 0)) (i32.const -1))
(call $assert_eq_i32 (i32.const 5102) (call $params (i32.const 1)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5201) (call $params_id (i32.const 0)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5202) (call $params_id (i32.const 1)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5301) (call $param_break (i32.const 0)) (i32.const -1))
(call $assert_eq_i32 (i32.const 5302) (call $param_break (i32.const 1)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5401) (call $params_break (i32.const 0)) (i32.const -1))
(call $assert_eq_i32 (i32.const 5402) (call $params_break (i32.const 1)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5501) (call $params_id_break (i32.const 0)) (i32.const 3))
(call $assert_eq_i32 (i32.const 5502) (call $params_id_break (i32.const 1)) (i32.const 3))

(call $assert_eq_i32 (i32.const 5601) (call $effects (i32.const 1)) (i32.const -14))
(call $assert_eq_i32 (i32.const 5602) (call $effects (i32.const 0)) (i32.const -6))

(call $assert_eq_i64_i32 (i32.const 5701) (call $add64_u_with_carry (i64.const 0) (i64.const 0) (i32.const 0))  (i64.const 0) (i32.const 0))
(call $assert_eq_i64_i32 (i32.const 5702) (call $add64_u_with_carry (i64.const 100) (i64.const 124) (i32.const 0))  (i64.const 224) (i32.const 0))
(call $assert_eq_i64_i32 (i32.const 5703) (call $add64_u_with_carry (i64.const -1) (i64.const 0) (i32.const 0))  (i64.const -1) (i32.const 0))
(call $assert_eq_i64_i32 (i32.const 5704) (call $add64_u_with_carry (i64.const -1) (i64.const 1) (i32.const 0))  (i64.const 0) (i32.const 1))
(call $assert_eq_i64_i32 (i32.const 5705) (call $add64_u_with_carry (i64.const -1) (i64.const -1) (i32.const 0))  (i64.const -2) (i32.const 1))
(call $assert_eq_i64_i32 (i32.const 5706) (call $add64_u_with_carry (i64.const -1) (i64.const 0) (i32.const 1))  (i64.const 0) (i32.const 1))
(call $assert_eq_i64_i32 (i32.const 5707) (call $add64_u_with_carry (i64.const -1) (i64.const 1) (i32.const 1))  (i64.const 1) (i32.const 1))
(call $assert_eq_i64_i32 (i32.const 5708) (call $add64_u_with_carry (i64.const 0x8000000000000000) (i64.const 0x8000000000000000) (i32.const 0)) (i64.const 0) (i32.const 1))

(call $assert_eq_i64 (i32.const 5801) (call $add64_u_saturated (i64.const 0) (i64.const 0)) (i64.const 0))
(call $assert_eq_i64 (i32.const 5802) (call $add64_u_saturated (i64.const 1230) (i64.const 23)) (i64.const 1253))
(call $assert_eq_i64 (i32.const 5803) (call $add64_u_saturated (i64.const -1) (i64.const 0)) (i64.const -1))
(call $assert_eq_i64 (i32.const 5804) (call $add64_u_saturated (i64.const -1) (i64.const 1)) (i64.const -1))
(call $assert_eq_i64 (i32.const 5805) (call $add64_u_saturated (i64.const -1) (i64.const -1)) (i64.const -1))
(call $assert_eq_i64 (i32.const 5806) (call $add64_u_saturated (i64.const 0x8000000000000000) (i64.const 0x8000000000000000)) (i64.const -1))

(call $type_use)

(call $wasi$print_i32_ln  (i32.const 666))
)
)
